//
//  YLWechatProcessor.swift
//  YLPaymentKit
//
//  Created by changhe on 2025/4/12.
//

import Foundation
import UIKit

@objc
/// 微信支付处理器实现
public class YLWechatProcessor: NSObject, YLPaymentProcessor, WXApiDelegate {
    // MARK: - 属性
    
    /// 支付类型
    public var paymentType: YLPaymentType {
        return .wechat
    }
    
    /// 是否可用（检查是否安装了微信）
    public var isAvailable: Bool {
        guard let urlScheme = URL(string: "weixin://") else { return false }
        return UIApplication.shared.canOpenURL(urlScheme)
    }
    
    /// 当前支付回调
    private var currentCallback: ((YLPaymentResult) -> Void)?
    
    /// 当前订单号
    private var currentOrderId: String?
    
    /// 微信APP ID
    private var wxAppId: String?
    
    /// 通用链接
    private var universalLink: String?
    
    // MARK: - 初始化与设置
    
    /// 设置交易更新回调
    public func setTransactionUpdatedCallback(_ callback: @escaping (YLTransactionInfo) -> Void) { }
    
    public func setup(config: YLPaymentConfig) {
        self.wxAppId = config.wxAppId
        self.universalLink = config.wxUniversalLink
        
        if let appId = config.wxAppId, let universalLink = config.wxUniversalLink {
            WXApi.registerApp(appId, universalLink: universalLink)
        }
    }
    
    // MARK: - 支付处理
   
    /// 处理支付（使用YLPaymentParams）
    public func handlePayment(params: YLPaymentParams, completion: @escaping (YLPaymentResult) -> Void) {
        // 保存回调和订单ID
        self.currentCallback = completion
        self.currentOrderId = params.orderId
        
        guard let _ = wxAppId, WXApi.isWXAppInstalled() else {
            completion(.failure(.cannotOpenPaymentApp))
            self.clearPaymentState()
            return
        }
        
        guard let wechatParams = params as? YLWechatParams else {
            completion(.failure(.invalidParameters))
            self.clearPaymentState()
            return
        }
        
        guard let partnerId = wechatParams.partnerId,
              let prepayId = wechatParams.prepayId,
              let nonceStr = wechatParams.nonceStr,
              let timeStampStr = wechatParams.timeStamp,
              let sign = wechatParams.sign else {
            completion(.failure(.invalidParameters))
            self.clearPaymentState()
            return
        }
        
        let timeStamp = UInt32(timeStampStr) ?? UInt32(Date().timeIntervalSince1970)
        
        let payRequest = PayReq()
        payRequest.partnerId = partnerId
        payRequest.prepayId = prepayId
        payRequest.nonceStr = nonceStr
        payRequest.timeStamp = timeStamp
        payRequest.package = wechatParams.package ?? "Sign=WXPay"
        payRequest.sign = sign
        
        WXApi.send(payRequest, completion: nil)
    }
    
    // MARK: - URL回调处理
    
    /// 能否处理URL
    public func canHandleURL(_ url: URL) -> Bool {
        return WXApi.isWXAppInstalled() && WXApi.handleOpen(url, delegate: self)
    }
    
    /// 处理URL回调
    public func handleURL(_ url: URL) -> Bool {
        return canHandleURL(url)
    }
    
    // MARK: - 结果处理
    
    /// 处理微信支付回调
    public func onResp(_ resp: BaseResp) {
        // -- 判断是否为支付的回调
        if let payResp = resp as? PayResp  {
            handleWXPayResponse(payResp)
        }
    }
    
    func handleWXPayResponse(_ response: PayResp) {
        switch response.errCode {
        case 0: // 支付成功
            let info: [String: Any] = [
                "errCode": response.errCode,
                "returnKey": response.returnKey
            ]
            
            let resultData = YLPaymentResultData(
                orderId: self.currentOrderId ?? "",
                transactionId: response.returnKey,
                productId: nil,
                transactionDate: Date(),
                originalTransactionId: nil,
                rawInfo: info
            )
            
            self.currentCallback?(.success(resultData))
            
        case -2: // 用户取消
            self.currentCallback?(.cancel)
            
        default: // 支付失败
            let errorMsg = "微信支付失败，错误码: \(response.errCode)"
            self.currentCallback?(.failure(.other(errorMsg)))
        }
        
        self.clearPaymentState()
    }
    
    /// 清除支付状态
    private func clearPaymentState() {
        self.currentCallback = nil
        self.currentOrderId = nil
    }
}
